package org.batatasframework.support.database;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.batatasframework.support.database.sql.TableRuntimeJoin;
import org.batatasframework.support.database.sql.TableRuntimeMaster;
import org.batatasframework.support.database.sql.QueryParameter;
import org.batatasframework.support.database.sql.field.FieldElement;
import org.batatasframework.support.database.sql.where.QueryFragment;


/**
 * 明要需要读取的数据库表
 * @author jackson
 *
 */
public class IdentifyTableBase extends AbstractTargetTable<TableRuntimeMaster>{

	private final IdentifyJoin[] joins;

	/** 如果是使用这种方式的话，那么会把这些查询语句组合成一个来查询的  */
	private IdentifyTableBase union;
	
	/** 本次查询需要添加进来的特殊条件；如：分表查询的，应该指定这个分表对象哪个范围的数据。 */
	private final List<QueryFragment> where = new ArrayList<>(1);
	
	public IdentifyTableBase(TableRuntimeMaster tableInstance, TableInfo tableInfo, IdentifyJoin... joins) {
		super(tableInstance, tableInfo);
		
		this.joins = joins;
	}

	public IdentifyTableBase(TableRuntimeMaster tableInstance) {
		super(tableInstance, tableInstance.getTableMetadata().getTableInfo());

		this.joins = new IdentifyJoin[tableInstance.getJoinSize()];
		int joinIndex = 0;
		for(TableRuntimeJoin jtr : tableInstance.getJoins()){
			joins[joinIndex++] = new IdentifyJoin(jtr);
		}
	}
	
	public void addQuery(QueryFragment query){
		where.add(query);
	}
	
	public IdentifyTableBase getUnion() {
		return union;
	}
	
	public void setUnion(IdentifyTableBase union) {
		this.union = union;
	}
	
	public String getWhereClause(List<QueryParameter> queryParamenters) throws Exception {
		if(where.isEmpty()) return "";
		
		StringBuilder buf = new StringBuilder( where.size() * 10 );
		for(QueryFragment qf : where){
			qf.parse(LogicSymbol.AND, buf, queryParamenters);
		}
		return buf.substring(LogicSymbol.AND.getValue().length());
	}
	
	public String getFromClause() throws Exception{
		
		StringBuilder buf = new StringBuilder();
		buf.append(getTargetTableName()).append(' ').append(getAlias());
		
		for(IdentifyJoin join : joins){
			String joinAlias = join.getAlias();

			buf.append(join.getJoinType()).append(join.getTargetTableName())
				.append(' ').append(joinAlias)
				.append(" on(").append(joinAlias)
				.append('.').append(join.getJoinField())
				.append('=').append(join.getTargetAlias())
				.append('.').append(join.getMasterField()).append(')');
	
		}
		
		return buf.toString();
	}
	
	public String getSelectClause() throws Exception{
		Collection<FieldElement> columns = tableInstance.getColumns();
		StringBuilder buf = new StringBuilder( columns.size() * 10 );
		buf.append(tableInstance.getAlias()).append('.').append(tableInstance.getPrimaryKey());
		
		for(FieldElement column : columns){
			column.toSqlString(buf.append(", "), this);
		}
		
		return buf.toString();
	}
	
	public static class IdentifyJoin extends AbstractTargetTable<TableRuntimeJoin>{
		
		public IdentifyJoin(TableRuntimeJoin joinTable, TableInfo tableInfo){
			super(joinTable, tableInfo);
		}
		
		public IdentifyJoin(TableRuntimeJoin joinTable){
			super(joinTable, joinTable.getTableMetadata().getTableInfo());
		}
		
		public String getJoinType(){
			return tableInstance.getJoinType();
		}
		
		public String getJoinField() {
			return tableInstance.getJoinField();
		}
		
		public String getMasterField() {
			return tableInstance.getMasterField();
		}
		
		public String getTargetAlias() {
			return tableInstance.getTargetAlias();
		}
	}
}
